package com.itheima.service.mongo.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.RandomUtil;
import com.itheima.domain.mongo.Friend;
import com.itheima.domain.mongo.RecommendUser;
import com.itheima.domain.mongo.UserLike;
import com.itheima.domain.mongo.Visitor;
import com.itheima.domain.vo.PageBeanVo;
import com.itheima.domain.vo.UserLikeCountVo;
import com.itheima.domain.vo.UserLikeVo;
import com.itheima.service.mongo.UserLikeService;
import org.apache.dubbo.config.annotation.Service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;

import java.util.ArrayList;
import java.util.List;

@Service // dubbo的
public class UserLikeServiceImpl implements UserLikeService {

    @Autowired
    private MongoTemplate mongoTemplate;

    @Override
    public void save(Long userId, Long likeUserId) {

        // 查询你是否已经喜欢过对方了。。
        boolean isExists = mongoTemplate.exists(Query.query(Criteria.where("userId").is(userId).and("likeUserId").is(likeUserId)), UserLike.class);

        if (!isExists) {
            // 封装实体
            UserLike userLike = new UserLike();
            userLike.setCreated(System.currentTimeMillis());
            userLike.setUserId(userId);
            userLike.setLikeUserId(likeUserId);
            // 保存
            mongoTemplate.save(userLike);
        }
    }

    @Override
    public Boolean isMutualLike(Long userId, Long likeUserId) {
        // 你喜欢对方
        boolean isExists1 = mongoTemplate.exists(Query.query(Criteria.where("userId").is(userId).and("likeUserId").is(likeUserId)), UserLike.class);
        // 对方喜欢你
        boolean isExists2 = mongoTemplate.exists(Query.query(Criteria.where("userId").is(likeUserId).and("likeUserId").is(userId)), UserLike.class);
        return isExists1 && isExists2;
    }

    @Override
    public void delete(Long userId, Long likeUserId) {
        // 你不喜欢对方
        mongoTemplate.remove(Query.query(Criteria.where("userId").is(userId).and("likeUserId").is(likeUserId)), UserLike.class);
    }

    @Override
    public UserLikeCountVo findUserLikeCount(Long userId) {
        // - 相互喜欢: 查询好友列表 (  从`friend`表中根据`userId`查询我的所有好友数量  )
        long eachLoveCount = mongoTemplate.count(Query.query(Criteria.where("userId").is(userId)), Friend.class);
        // - 喜欢: 查询你喜欢的用户 (  从`user_like`表中根据`userId`查询所有我喜欢的用户数量  )
        long loveCount = mongoTemplate.count(Query.query(Criteria.where("userId").is(userId)), UserLike.class);
        // - 粉丝: 查询别人喜欢你的用户 (  从`user_like`表中根据`likeUserId`查询所有喜欢我的用户数量 )
        long fanCount = mongoTemplate.count(Query.query(Criteria.where("likeUserId").is(userId)), UserLike.class);
        // 封装vo并返回
        return new UserLikeCountVo(eachLoveCount, loveCount, fanCount);
    }

    @Override
    public PageBeanVo findByPage(Long userId, Integer type, Integer pageNum, Integer pageSize) {
        Integer index = (pageNum - 1) * pageSize;

        switch (type) {
            case 1: {
                // 相互喜欢: 查询好友列表 ( 从`friend`表中根据`userId`分页查询我的好友 )
                // 1-1 查询friendList和统计
                List<Friend> friendList = mongoTemplate.find(Query.query(Criteria.where("userId").is(userId)), Friend.class);
                long count = mongoTemplate.count(Query.query(Criteria.where("userId").is(userId)), Friend.class);
                // 1-2 封装userLikeVo
                List<UserLikeVo> voList = new ArrayList<>();
                if (CollectionUtil.isNotEmpty(friendList)) {
                    for (Friend friend : friendList) {
                        // 获取对方id
                        Long friendId = friend.getFriendId();
                        // 创建vo
                        UserLikeVo userLikeVo = new UserLikeVo();
                        userLikeVo.setId(friendId);
                        userLikeVo.setMatchRate(findScore(userId, friendId).intValue());

                        // 添加到集合中
                        voList.add(userLikeVo);

                    }
                }
                // 1-3 返回并封装pageBeanVo
                return new PageBeanVo(pageNum, pageSize, count, voList);
            }
            case 2: {
                // 喜欢: 查询你喜欢的用户 ( 从`user_like`表中根据`userId`分页查询我喜欢的用户 )
                // 2-1 查询userLikeList 和 统计
                List<UserLike> userLikeList = mongoTemplate.find(Query.query(Criteria.where("userId").is(userId)), UserLike.class);
                long count = mongoTemplate.count(Query.query(Criteria.where("userId").is(userId)), UserLike.class);
                // 2-2 封装userLikeVo
                List<UserLikeVo> voList = new ArrayList<>();
                if (CollectionUtil.isNotEmpty(userLikeList)) {
                    for (UserLike userLike : userLikeList) {
                        // 获取对方id
                        Long friendId = userLike.getLikeUserId();
                        // 创建vo
                        UserLikeVo userLikeVo = new UserLikeVo();
                        userLikeVo.setId(friendId);
                        userLikeVo.setMatchRate(findScore(userId, friendId).intValue());
                        // 添加到list
                        voList.add(userLikeVo);
                    }
                }
                // 2-3 返回并封装pageBeanVo
                return new PageBeanVo(pageNum, pageSize, count, voList);
            }
            case 3: {
                // 粉丝: 查询别人喜欢你的用户 ( 从`user_like`表中根据`likeUserId`分页查询喜欢我的用户 )
                // 3-1 查询userLikeList 和 统计
                List<UserLike> userLikeList = mongoTemplate.find(Query.query(Criteria.where("likeUserId").is(userId)), UserLike.class);
                long count = mongoTemplate.count(Query.query(Criteria.where("likeUserId").is(userId)), UserLike.class);
                // 3-2 封装userLikeVo
                List<UserLikeVo> voList = new ArrayList<>();
                if (CollectionUtil.isNotEmpty(userLikeList)) {
                    for (UserLike userLike : userLikeList) {
                        // 获取对方id
                        Long friendId = userLike.getUserId();
                        // 创建vo
                        UserLikeVo userLikeVo = new UserLikeVo();
                        userLikeVo.setId(friendId);
                        userLikeVo.setMatchRate(findScore(userId, friendId).intValue());

                        // 添加并判断是否为相互喜欢
                        userLikeVo.setAlreadyLove(isMutualLike(userId, friendId));

                        // 添加到list
                        voList.add(userLikeVo);
                    }
                }
                // 3-3 返回并封装pageBeanVo
                return new PageBeanVo(pageNum, pageSize, count, voList);

            }
            case 4: {
                // 谁看过我: 查询访客列表( 从`visitor`表中根据`userId`分页查询访问过的用户 )
                // 4-1 查询visitorList 和 统计
                List<Visitor> visitorList = mongoTemplate.find(Query.query(Criteria.where("userId").is(userId)), Visitor.class);
                long count = mongoTemplate.count(Query.query(Criteria.where("userId").is(userId)), Visitor.class);
                // 4-2 封装userLikeVo
                List<UserLikeVo> voList = new ArrayList<>();
                if (CollectionUtil.isNotEmpty(visitorList)) {
                    for (Visitor visitor : visitorList) {
                        // 获取对方id
                        Long friendId = visitor.getVisitorUserId();
                        // 创建vo
                        UserLikeVo userLikeVo = new UserLikeVo();
                        userLikeVo.setId(friendId);
                        userLikeVo.setMatchRate(findScore(userId, friendId).intValue());
                        // 添加到list
                        voList.add(userLikeVo);
                    }
                }
                // 4-3 返回并封装pageBeanVo
                return new PageBeanVo(pageNum, pageSize, count, voList);
            }
        }
        return null;
    }

    // 查询缘分值
    private Double findScore(Long userId, Long friendId) {
        RecommendUser recommendUser = mongoTemplate.findOne(Query.query(Criteria.where("userId").is(friendId).and("toUserId").is(userId)), RecommendUser.class);
        if (recommendUser == null) {
            recommendUser = new RecommendUser();
            recommendUser.setScore(RandomUtil.randomDouble(60, 80));
        }
        return recommendUser.getScore();
    }
}
